using System;
using System.Text;
using System.Diagnostics;
using System.Collections.Generic;
using My.IdlConverter.Core;
using My.IdlConverter.Core.Graphics;
using My.IdlConverter.Core.Filters;
using My.IdlConverter.Core.Util;

namespace My.IdlConverter.Com
{
    public class ComMyFitTemplateLibrary : ComLibraryTemplate
    {
        public ComMyFitTemplateLibrary()
        {
        }

        public ComMyFitTemplateLibrary(ClassForest forest)
            :base(forest)
        {
        }

        public override StringBuilder New()
        {
            //import libs
            IDictionary<string, StringBuilder> contents = DefaultContents;
            StringBuilder importLibraries = contents[ImportLib];
            foreach(string nextLibName in ImportLibraries)
            {
                importLibraries.AppendFormat(StringUtil.FormatIndent1("importlib(\"{0}\");\n",nextLibName));
            }

            //registar
            StringBuilder registar = contents[Registar];
            registar.AppendLine(StringUtil.FormatIndent1("["));
            registar.AppendFormat(StringUtil.FormatIndent2("uuid({0}),\n",ComGuidCenter.Apply("CRegistar")));
            registar.AppendLine(StringUtil.FormatIndent2("helpstring(\"ComponentRegistrar Class\")"));
            registar.AppendLine(StringUtil.FormatIndent1("]"));
            registar.AppendLine(StringUtil.FormatIndent1("coclass CompReg"));
            registar.AppendLine(StringUtil.FormatIndent1("{"));
            registar.AppendLine(StringUtil.FormatIndent1("[default] interface IComponentRegistrar;"));
            registar.AppendLine(StringUtil.FormatIndent1("};"));

            //coclass
            StringBuilder coClass = contents[CoClass];
            Class refClass = null;
            foreach (ClassTree nextNode in Consumer.ChildTrees)
            {
                refClass = nextNode.ReferObj as Class;
                Debug.Assert(refClass != null);
                coClass.AppendLine(StringUtil.FormatIndent1("["));
                coClass.AppendFormat(StringUtil.FormatIndent2("uuid({0}),\n", ComGuidCenter.Apply(refClass.Name)));
                coClass.AppendFormat(StringUtil.FormatIndent2("helpstring(\"{0} Class\")\n",ClassModifier.GetTitle(refClass.Name)));
                coClass.AppendLine(StringUtil.FormatIndent1("]"));
                coClass.AppendFormat(StringUtil.FormatIndent1("coclass {0}\n", ClassModifier.GetTitle(refClass.Name)));
                coClass.AppendLine(StringUtil.FormatIndent1("{"));
                IList<Interface> pureBaseInterfaces = new List<Interface>();
                refClass.GetPureBaseInterfaces(ref pureBaseInterfaces);
                this.AppendDefaultInterface(coClass, refClass, pureBaseInterfaces);
                foreach (Interface nextInterface in pureBaseInterfaces)
                {
                    coClass.AppendFormat(StringUtil.FormatIndent2("interface {0};\n", InterfaceModifier.GetName(nextInterface.Name)));
                }

                coClass.AppendLine(StringUtil.FormatIndent1("};"));
                coClass.AppendLine();
            }

            return base.New();
        }

        public override string ToString()
        {
            return base.ToString();
        }

        protected override void Reset()
        {
            base.Reset();

            Properties[CustomString] = DefaultCustom;
            Properties[VersionString] = DefaultVersion;
            Properties[LibraryName] = DefaultLibraryName;
        }

        private void AppendDefaultInterface(StringBuilder coClass, Class classObj, IList<Interface> pureBaseInterfaces)
        {
            string classClueWord = classObj.ClueWord;
            bool found = false;
            foreach (Interface nextInterface in pureBaseInterfaces)
            {
                if (classClueWord.Equals(nextInterface.ClueWord))
                {
                    coClass.AppendFormat(StringUtil.FormatIndent2("[default] interface {0};\n", InterfaceModifier.GetName(nextInterface.Name)));
                    pureBaseInterfaces.Remove(nextInterface);
                    found = true;
                    break;
                }
            }

            if (!found)
            {
                if (pureBaseInterfaces.Count > 0)
                {
                    coClass.AppendFormat(StringUtil.FormatIndent2("[default] interface {0};\n", InterfaceModifier.GetName(pureBaseInterfaces[0].Name)));
                    pureBaseInterfaces.RemoveAt(0);
                }
            }
        }
    }
}
